﻿using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Principal;
using System.ServiceModel;
using Microsoft.SharePoint;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Navigant.DataContracts;
using Navigant.Infrastructure.Cases;
using Navigant.Mapping;
using Navigant.Model.Custodians;
using Navigant.Model.PreservationNotices;
using Navigant.ServiceInterfaces;

namespace Navigant.UnitTests.WebServices
{
    [TestClass()]
    public class PreservationNoticeServiceTests
    {
        public TestContext TestContext { get; set; }
        private string caseSiteUrl;

        public PreservationNoticeServiceTests()
        {
            this.caseSiteUrl = ConfigurationManager.AppSettings["testCaseSite"];
        }

        #region PreservationNoticeClient

        private class PreservationNoticeClient : ClientBase<IPreservationNoticeService>, IPreservationNoticeService
        {
            public PreservationNoticeClient()
            {
                this.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
            }
        
            #region IPreservationNoticeService Members

            public List<PreservationNoticeTemplateContract> GetTemplates(CaseContract parentCase)
            {
                return this.Channel.GetTemplates(parentCase);
            }

            public int SaveTemplate(PreservationNoticeTemplateContract template)
            {
                return this.Channel.SaveTemplate(template);
            }

            public List<CustodianContract> SendNotices(CaseContract currentCase, 
                List<int> custodianIdentifiers, int preservationNoticeTemplateId, string fromAddress)
            {
                return this.Channel.SendNotices(currentCase, custodianIdentifiers, 
                    preservationNoticeTemplateId, fromAddress);
            }

            public GetPreservationNoticesResultContract GetPreservationNotices(CaseContract parentCase, 
                int pageSize, int currentPage)
            {
                return this.Channel.GetPreservationNotices(parentCase, pageSize, currentPage);
            }

            #endregion
        }

        #endregion

        #region GetParentCase

        private CaseContract GetParentCase()
        {
            CaseContract parentCase = new CaseContract();
            using (SPSite site = new SPSite(this.caseSiteUrl))
            {
                parentCase.ClientPortalId = site.ID;
                using (SPWeb web = site.OpenWeb())
                {
                    parentCase.Id = web.ID;
                    parentCase.Name = web.Title;
                }
            }
            return parentCase;
        }

        #endregion

        [TestMethod()]
        public void GetTemplatesFromService()
        {
            IPreservationNoticeService service = new PreservationNoticeClient();
            List<PreservationNoticeTemplateContract> templates = service.GetTemplates(this.GetParentCase());
            Assert.IsTrue(templates.Count > 0);
        }

        [TestMethod()]
        public void AddTemplateUsingService()
        {
            CaseContract parentCase = this.GetParentCase();
            PreservationNoticeTemplateContract template = new PreservationNoticeTemplateContract();
            template.ParentCase = parentCase;
            template.Name = "AddTemplateUsingService Name";
            template.Subject = "AddTemplateUsingService Subject";
            template.Body = "[Image|hi.jpg] </br> The message body for AddTemplateUsingService template.  [URL] ";
            IPreservationNoticeService service = new PreservationNoticeClient();
            int templateId = service.SaveTemplate(template);
            Assert.IsTrue(templateId > 0);
            this.TestContext.WriteLine("New Template ID:  {0}", templateId);
        }

        [TestMethod()]
        public void SendNoticesUsingService()
        {
            CaseContract parentCaseContract = this.GetParentCase();
            ICase parentCase = Converter.ToCase(parentCaseContract);
            CustodianService custodianService = new CustodianService(parentCase);
            IEnumerable<Custodian> custodians = custodianService.FindAll().Take(10);
            List<int> custodianIdentifiers = new List<int>();
            foreach (Custodian custodian in custodians)
            {
                custodianIdentifiers.Add(custodian.Id); 
            }
            PreservationNoticeTemplateService templateService = new PreservationNoticeTemplateService(parentCase);
            int preservationNoticeTemplateId = templateService.FindAll().FirstOrDefault().Id;
            string fromAddress = "SendNoticesUsingService@test.com";
            IPreservationNoticeService service = new PreservationNoticeClient();
            List<CustodianContract> sendErrors = service.SendNotices(this.GetParentCase(),
                custodianIdentifiers, preservationNoticeTemplateId, fromAddress);
            Assert.IsTrue(sendErrors.Count == 0);
        }

        [TestMethod()]
        public void GetNoticesFromService()
        {
            IPreservationNoticeService service = new PreservationNoticeClient();
            GetPreservationNoticesResultContract results = service.GetPreservationNotices(this.GetParentCase(), 25, 1);
            Assert.IsTrue(results.Result.Count > 0);
            Assert.IsTrue(results.TotalCount > 0);
            this.TestContext.WriteLine("Total Count for Current Page:  {0}", results.Result.Count);
            this.TestContext.WriteLine("Total Count Overall:  {0}", results.TotalCount);
        }
    }
}
